from flask import Flask, Response
from picamera2 import Picamera2
import cv2

app = Flask(__name__)
picam2 = Picamera2()
# 配置摄像头输出为 RGB 格式（方便 OpenCV 处理）
config = picam2.create_video_configuration(main={"size": (640, 480), "format": "RGB888"})
picam2.configure(config)
picam2.start()

def generate_mjpeg():
    while True:
        # 读取一帧图像（numpy 数组，RGB 格式，来自 picamera2）
        frame = picam2.capture_array()  # picamera2 输出为 RGB
        
        # 关键修正：不需要转 BGR，直接用 RGB 编码为 JPEG
        # 原错误：frame_bgr = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        # 正确做法：保持 RGB 格式，直接编码
        ret, buffer = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 80])
        
        if not ret:
            continue
        # 按 MJPEG 协议格式返回
        yield (b'--frame\r\n'
               b'Content-Type: image/jpeg\r\n\r\n' + buffer.tobytes() + b'\r\n')

@app.route('/video_feed')
def video_feed():
    # 返回 MJPEG 流响应
    return Response(
        generate_mjpeg(),
        mimetype='multipart/x-mixed-replace; boundary=frame'
    )

@app.route('/')
def index():
    # 主页：嵌入视频流
    return '''
    <html>
      <head>
        <title>MJPEG 视频流</title>
      </head>
      <body>
        <h2>实时视频流</h2>
        <!-- 直接显示 MJPEG 流 -->
        <img src="/video_feed" width="640" height="480">
      </body>
    </html>
    '''

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, threaded=True)  # threaded=True 支持并发